﻿package baseEngine.utils
{
    import baseEngine.core.*;
    import baseEngine.system.*;
    import com.gengine.resource.*;
    import flash.display.*;
    import flash.display3D.*;
    import flash.display3D.textures.*;
    import flash.filters.*;
    import flash.geom.*;
    import flash.utils.*;

    public class Texture3DUtils extends Object
    {
        private static var normalMapData:ByteArray;
        private static var shader:Shader;
        private static var filter:ShaderFilter;
        private static var textureByRequest:Dictionary = new Dictionary(false);
        private static var _id:int = 0;
        private static var idMap:Dictionary = new Dictionary(false);

        public function Texture3DUtils()
        {
            return;
        }// end function

        public static function toNormalMap(param1:BitmapData, param2:Number = 1, param3:Number = 1) : BitmapData
        {
            if (!normalMapData)
            {
                shader.data.x.value = [param2];
                shader.data.y.value = [param3];
                filter = new ShaderFilter(shader);
            }
            param1.applyFilter(param1, param1.rect, new Point(), filter);
            return param1;
        }// end function

        public static function unloadTexture(param1, param2:int) : void
        {
            var _loc_4:TextureBase = null;
            var _loc_3:* = getTexureId(param1, param2);
            if (textureByRequest[_loc_3])
            {
                _loc_4 = textureByRequest[_loc_3];
                delete textureByRequest[_loc_3];
                _loc_4.dispose();
                _loc_4 = null;
            }
            delete idMap[param1];
            return;
        }// end function

        public static function unloadTextureWithoutDeleteMapID(param1, param2:int) : void
        {
            var _loc_4:TextureBase = null;
            var _loc_3:* = getTexureId(param1, param2);
            if (textureByRequest[_loc_3])
            {
                _loc_4 = textureByRequest[_loc_3];
                delete textureByRequest[_loc_3];
                _loc_4.dispose();
                _loc_4 = null;
            }
            return;
        }// end function

        public static function getTexureId(param1, param2:int) : String
        {
            var _loc_3:* = idMap[param1];
            if (!_loc_3)
            {
                var _loc_4:* = String(_id);
                _loc_3 = String(_id);
                idMap[param1] = _loc_4;
                var _loc_5:* = _id + 1;
                _id = _loc_5;
            }
            return _loc_3 + ":" + param2;
        }// end function

        public static function createTexture(param1, param2, param3:int, param4:int, param5:int, param6:Boolean) : TextureBase
        {
            var _loc_9:int = 0;
            var _loc_11:String = null;
            var _loc_12:int = 0;
            var _loc_14:TextureBase = null;
            var _loc_15:ByteArray = null;
            var _loc_16:int = 0;
            var _loc_17:Number = NaN;
            var _loc_18:Number = NaN;
            var _loc_7:* = getTexureId(param1, param5);
            if (textureByRequest[_loc_7])
            {
                return textureByRequest[_loc_7];
            }
            var _loc_8:* = param5 != Texture3D.MIP_NONE;
            var _loc_10:int = 0;
            var _loc_13:* = Global3D.scene.context;
            if (!_loc_13 || !param2)
            {
                return null;
            }
            if (param3 == TextureFormat.FORMAT_RGBA)
            {
                if (param2 is Point)
                {
                    _loc_14 = _loc_13.createTexture(param2.x, param2.y, Context3DTextureFormat.BGRA, param6);
                    _loc_13.setRenderToTexture(_loc_14);
                    _loc_13.clear();
                    _loc_13.setRenderToBackBuffer();
                }
                else
                {
                    _loc_14 = uploadWithMipmaps(null, param2, 0, _loc_8, param4, param6, param1);
                }
            }
            else if (param3 == TextureFormat.FORMAT_COMPRESSED || param3 == TextureFormat.FORMAT_COMPRESSED_ALPHA || param3 == TextureFormat.FORMAT_COMPRESSED_BGRA)
            {
                _loc_15 = param2 as ByteArray;
                if (_loc_15[6] == 255)
                {
                    _loc_15.position = 12;
                }
                else
                {
                    _loc_15.position = 6;
                }
                _loc_16 = _loc_15.readUnsignedByte();
                switch(_loc_16)
                {
                    case 0:
                    case 1:
                    {
                        _loc_11 = Context3DTextureFormat.BGRA;
                        break;
                    }
                    case 2:
                    case 3:
                    {
                        _loc_11 = Context3DTextureFormat.COMPRESSED;
                        break;
                    }
                    case 4:
                    case 5:
                    {
                        _loc_11 = "compressedAlpha";
                        break;
                    }
                    default:
                    {
                        break;
                    }
                }
                _loc_17 = Math.pow(2, _loc_15.readUnsignedByte());
                _loc_18 = Math.pow(2, _loc_15.readUnsignedByte());
                if (_loc_10 == 0)
                {
                    _loc_14 = _loc_13.createTexture(_loc_17, _loc_18, _loc_11, param6);
                    Texture(_loc_14).uploadCompressedTextureFromByteArray(_loc_15, 0, false);
                }
                else
                {
                    _loc_14 = _loc_13.createCubeTexture(_loc_17, _loc_11, param6);
                    CubeTexture(_loc_14).uploadCompressedTextureFromByteArray(_loc_15, 0, false);
                }
            }
            else if (param3 == TextureFormat.FORMAT_CUBEMAP && param2 is Array)
            {
                if (param2 is Point)
                {
                    _loc_14 = _loc_13.createCubeTexture(param2.x, Context3DTextureFormat.BGRA, param6);
                }
                else
                {
                    _loc_14 = _loc_13.createCubeTexture(512, Context3DTextureFormat.BGRA, param6);
                }
                _loc_12 = 0;
                while (_loc_12 < 6)
                {
                    
                    generateMipMaps(param2[_loc_12], _loc_14, null, param2[_loc_12].transparent, _loc_12);
                    _loc_12++;
                }
            }
            textureByRequest[_loc_7] = _loc_14;
            return _loc_14;
        }// end function

        private static function uploadWithMipmaps(param1:TextureBase, param2:BitmapData, param3:int, param4:Boolean, param5:int, param6:Boolean, param7) : TextureBase
        {
            var _loc_8:BitmapData = null;
            var _loc_9:BitmapData = null;
            var _loc_18:int = 0;
            var _loc_19:BitmapData = null;
            var _loc_20:BitmapData = null;
            var _loc_21:Context3D = null;
            var _loc_10:* = Global3D.maxTextureSize;
            var _loc_11:* = param2.width < _loc_10 ? (param2.width) : (_loc_10);
            var _loc_12:* = param2.height < _loc_10 ? (param2.height) : (_loc_10);
            var _loc_13:int = 1;
            while (_loc_13 < _loc_11)
            {
                
                _loc_13 = _loc_13 << 1;
            }
            var _loc_14:int = 1;
            while (_loc_14 < _loc_12)
            {
                
                _loc_14 = _loc_14 << 1;
            }
            if (!param1)
            {
                _loc_21 = Global3D.scene.context;
                param1 = _loc_21.createTexture(_loc_13, _loc_14, Context3DTextureFormat.BGRA, param6);
            }
            var _loc_15:* = new Matrix(_loc_13 / param2.width, 0, 0, _loc_14 / param2.height);
            var _loc_16:* = param2.rect;
            var _loc_17:* = new Rectangle();
            if (!param4)
            {
                if (_loc_13 != _loc_11 || _loc_14 != _loc_12)
                {
                    if (!_loc_19)
                    {
                        _loc_19 = new BitmapData(_loc_13, _loc_14, true, 0);
                    }
                    else
                    {
                        _loc_19.fillRect(_loc_19.rect, 0);
                    }
                    _loc_19.draw(param2, _loc_15, null, null, null, true);
                }
                if (param5 == Texture3D.TYPE_2D)
                {
                    Texture(param1).uploadFromBitmapData(_loc_19 || param2, 0);
                }
                else if (param5 == Texture3D.TYPE_CUBE)
                {
                    CubeTexture(param1).uploadFromBitmapData(_loc_19 || param2, param3, 0);
                }
            }
            else
            {
                _loc_20 = param2.clone();
                while (_loc_13 >= 1 || _loc_14 >= 1)
                {
                    
                    if (_loc_13 == _loc_11 && _loc_14 == _loc_12)
                    {
                        if (param5 == Texture3D.TYPE_2D)
                        {
                            Texture(param1).uploadFromBitmapData(param2, _loc_18);
                        }
                        else if (param5 == Texture3D.TYPE_CUBE)
                        {
                            CubeTexture(param1).uploadFromBitmapData(param2, param3, _loc_18);
                        }
                    }
                    else
                    {
                        _loc_17.width = _loc_13;
                        _loc_17.height = _loc_14;
                        if (!_loc_19)
                        {
                            _loc_19 = new BitmapData(_loc_13 || 1, _loc_14 || 1, true, 0);
                        }
                        else
                        {
                            _loc_19.fillRect(_loc_17, 0);
                        }
                        _loc_19.draw(_loc_20, _loc_15, null, null, _loc_17, true);
                        if (param5 == Texture3D.TYPE_2D)
                        {
                            Texture(param1).uploadFromBitmapData(_loc_19, _loc_18);
                        }
                        else if (param5 == Texture3D.TYPE_CUBE)
                        {
                            CubeTexture(param1).uploadFromBitmapData(_loc_19, param3, _loc_18);
                        }
                    }
                    if (_loc_19)
                    {
                        _loc_8 = _loc_20;
                        _loc_20 = _loc_19;
                        _loc_19 = _loc_8;
                    }
                    _loc_15.a = 0.5;
                    _loc_15.d = 0.5;
                    _loc_13 = _loc_13 >> 1;
                    _loc_14 = _loc_14 >> 1;
                    _loc_18++;
                }
            }
            return param1;
        }// end function

        public static function generateMipMaps(param1:BitmapData, param2:TextureBase, param3:BitmapData = null, param4:Boolean = false, param5:int = -1) : void
        {
            var _loc_10:uint = 0;
            var _loc_6:* = new Matrix();
            var _loc_7:* = new Rectangle();
            var _loc_8:* = param1.width;
            var _loc_9:* = param1.height;
            var _loc_11:* = param3 != null;
            param3 = param3 || new BitmapData(_loc_8, _loc_9, param4);
            _loc_7.width = _loc_8;
            _loc_7.height = _loc_9;
            while (_loc_8 >= 1 || _loc_9 >= 1)
            {
                
                if (param4)
                {
                    param3.fillRect(_loc_7, 0);
                }
                _loc_6.a = _loc_7.width / param1.width;
                _loc_6.d = _loc_7.height / param1.height;
                param3.draw(param1, _loc_6, null, null, null, true);
                if (param2 is Texture)
                {
                    Texture(param2).uploadFromBitmapData(param3, _loc_10++);
                }
                else
                {
                    CubeTexture(param2).uploadFromBitmapData(param3, param5, _loc_10++);
                }
                _loc_8 = _loc_8 >> 1;
                _loc_9 = _loc_9 >> 1;
                _loc_7.width = _loc_8 > 1 ? (_loc_8) : (1);
                _loc_7.height = _loc_9 > 1 ? (_loc_9) : (1);
            }
            if (!_loc_11)
            {
                param3.dispose();
            }
            return;
        }// end function

        public static function extractCubeMap(param1:BitmapData) : Array
        {
            var _loc_2:Array = null;
            var _loc_3:BitmapData = null;
            var _loc_8:int = 0;
            var _loc_4:Array = [];
            var _loc_5:* = new Matrix();
            var _loc_6:* = param1;
            var _loc_7:* = _loc_6.width > _loc_6.height ? (_loc_6.width / 4) : (_loc_6.width / 3);
            if (_loc_6.width > _loc_6.height)
            {
                _loc_2 = [2, 1, 0, 0, 1, 0, 1, 0, 0, 1, 2, 0, 1, 1, 0, 3, 1, 0];
            }
            else
            {
                _loc_2 = [2, 1, 0, 0, 1, 0, 1, 0, 0, 1, 2, 0, 1, 1, 0, 2, 4, Math.PI];
            }
            while (_loc_8 < 6)
            {
                
                _loc_3 = new BitmapData(_loc_7, _loc_7, _loc_6.transparent, 0);
                _loc_5.identity();
                _loc_5.translate((-_loc_7) * _loc_2[_loc_8 * 3], (-_loc_7) * _loc_2[_loc_8 * 3 + 1]);
                _loc_5.rotate(_loc_2[_loc_8 * 3 + 2]);
                _loc_3.fillRect(_loc_3.rect, 0);
                _loc_3.draw(_loc_6, _loc_5);
                _loc_4.push(_loc_3);
                _loc_8++;
            }
            return _loc_4;
        }// end function

    }
}
